import { Permission } from "@prisma/client";
import prisma from "../prisma_client";
import { z } from "zod";
import { convertNullToUndefined } from "~/utils";

const zodPermission = z.object({
  id: z.string().transform((v) => parseInt(v, 10)).optional(),
  parent_id: z.string().transform((v) => parseInt(v, 10)).optional(),
  name: z.string().optional(),
  zh_name: z.string().optional(),
  type: z.string().transform((v) => parseInt(v, 10)).optional(),
  path: z.string().optional(),
  icon: z.string().optional(),
  sort: z.string().transform((v) => parseInt(v, 10)).optional(),
  created_at: z.string().transform((v) => new Date(v)).optional(),
  updated_at: z.string().transform((v) => v ? new Date(v) : null).optional(),
  status: z.string().transform((v) => parseInt(v, 10)).optional(),
});

export const zPermission = zodPermission.extend({
  children: z.array(z.lazy(() => zodPermission)).optional(),
  parent: z.lazy(() => zodPermission).optional(),
});

export type PermissionModel = z.infer<typeof zPermission>;

export async function createPermission(value: PermissionModel) {
  const result = await prisma.permission.create({
    data: {
      ...value, // Spread the values object to include all fields
      children: undefined,
      parent: undefined,
      id: undefined,
      parent_id: value.parent_id ?? null,
      zh_name: value.zh_name ?? "",
      created_at: new Date(),
      status: 1,
    },
  });
  return result;
}

export async function findAllPermission(column?: string, order?: string, type?: number) {
  const permissions = await prisma.permission.findMany({
    where: {
      type: type ?? undefined
    },
    orderBy: {
      [column || "sort"]: order || "asc",
    },
  });
  return buildPermissionTree(permissions);
}

export function buildPermissionTree(permissions: Permission[]): PermissionModel[] {
  const map: { [key: number]: PermissionModel } = {};
  const roots: PermissionModel[] = [];

  // 将所有节点放入 map 中
  permissions.forEach(permission => {
    const model = convertNullToUndefined(permission);
    map[permission.id] = { ...model, children: [] };
  });

  // 构建树形结构
  permissions.forEach(permission => {
    if (permission.parent_id !== null && map[permission.parent_id]) {
      map[permission.parent_id].children!.push(map[permission.id]);
    } else {
      roots.push(map[permission.id]);
    }
  });

  return roots;
}

export async function getPermissionById(id: number) {
  return await prisma.permission.findUnique({
    where: { id: id },
  });
}

export async function updatePermission(value: PermissionModel) {
  const result = await prisma.permission.update({
    where: { id: value.id },
    data: {
      ...value, // Spread the values object to include all fields
      updated_at: new Date(),
      parent_id: value.parent_id ? null : value.parent_id === 0? null : value.parent_id,
      children: undefined,
      parent: undefined,
    },
  });
  return result;
}

export async function deletePermission(id: number) {
  const hasChildren = await prisma.permission.findFirst({
    where: { parent_id: id },
  });
  if (hasChildren) {
    return false;
  }
  return await prisma.permission.delete({
    where: { id: id },
  });
}
